package br.com.iswe.teste.web;

import java.io.IOException;
import java.text.SimpleDateFormat;

import org.xml.sax.SAXException;

import br.com.iswe.teste.dados.TestDataManager;

import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebLink;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;
import com.meterware.httpunit.WebWindow;

public abstract class BasicManterHttpTestCase extends HttpTestCase {
	public BasicManterHttpTestCase(String metodoTest, BasicTesteSuite basicTesteSuite) {
		super(metodoTest, basicTesteSuite);
	}

	//Constantes Gerais para todos os test cases
	//Sao de acordo com o padrao de geracao do ISWE.
	//TODO:Pensar em ter uma classe de constantes, que seria utilizado em toda a aplicacao. nos JSPs, calsses de teste e etc.
	public static final String TEXTO_TESTE_HTTP_UNIT_PREFIX    = "Teste HttpUnit : ";
	//public static final String TEXTO_TESTE_HTTP_UNIT_INSERT    = TEXTO_TESTE_HTTP_UNIT_PREFIX + "Insert";
	//public static final String TEXTO_TESTE_HTTP_UNIT_ALTERACAO = TEXTO_TESTE_HTTP_UNIT_PREFIX + "Alteracao";
	protected static final String SEPARADOR 		= ":";
	protected static final String LINK_DETALHE 		= "linkDetalhe";
	protected static final String LINK_INSERIR 		= "linkInserir";
	protected static final String LINK_EDITAR		= "linkEditar";
	protected static final String LINK_SALVAR 		= "linkSalvar";
	protected static final String LINK_ADICIONAR	= "linkAdicionar";
	protected static final String LINK_CONSULTAR 	= "linkConsultar";
	protected static final String LINK_DELETAR 		= "linkDeletar";
	protected static final String ITEM_SELECIONADO  = "itemSelecionado";
	//SubViews das paginas.
	protected static final String SUB_VIEW_MESTRE_DETALHES_ALTERAR = "mestreDetalhesSubViewAlterar";
	
	//Prefixos e Pos Fixos da aplicacao.
	protected static final String LST_PREFIX = "lst";
	protected static final String LST_CONSULTA_PREFIX = "lstConsulta";
	protected static final String FORM_POSTFIX = "Form";

	protected abstract String getBeanName();
	protected abstract String getCampoDescricao();
	
	protected SimpleDateFormat dtFmt = new SimpleDateFormat("dd/MM/yyyy");//TODO:Pensar em configurar isso.
	
	/**
	 * Retorna o nome do formulario de acordo com o nome do Bean
	 * seguindo os padroes dos casos de uso do tipo "Manter"
	 * @return
	 */
	protected String getFormName(){
		return getBeanName() + FORM_POSTFIX;
	}
	/**
	 * Retorna o nome da lista de consulta de acordo com o nome do Bean
	 * seguindo os padroes dos casos de uso do tipo "Manter"
	 * @return
	 */
	protected String getListaConsulta(){
		return LST_CONSULTA_PREFIX + getBeanName();
	}
	
	/**
	 * Mensagem mostrada na tela quando um registro � deletado com suscesso.
	 * @return
	 */
	protected String getMsgRemovidoSuscesso() {
		return "Registro removido com sucesso.";
	}
	
	/**
	 * Mensagem mostrada na tela quando um registor � inserido com suscesso.
	 * @return
	 */
	protected String getMsgSalvoSuscesso() {
		return "Registro gravado com sucesso.";//TODO:Recuperar esse dado de um messageresource.
	}

	/**
	 * Testa a funcionalidade de consulta de acordo com o cenario configurado.
	 * @throws SAXException 
	 * @throws IOException 
	 */
	protected void doConsulta() throws IOException, SAXException{
		//Obtem o formulario de consulta
		WebForm formConsulta = getExecInfo().getResp().getFormWithName(getFormName());
		
		//popula com um campo para consulta
        String valorDescricao = TestDataManager.getInstance(this.getClass()).getStringValue(getThreadNum(), getCampoDescricao());
		formConsulta.setParameter(getFormName() + SEPARADOR + getCampoDescricao(), valorDescricao);
		
		//submete o filtro
		WebLink linkConsultar = getExecInfo().getResp().getLinkWithID(getFormName() + SEPARADOR + LINK_CONSULTAR);
		linkConsultar.click();
		//obtem a pagina de resultado da pesquisa, apos executar o link.
		getExecInfo().setResp( getExecInfo().getWc().getCurrentPage() );
		//verifica o resultado da pesquisa
		WebTable table = getExecInfo().getResp().getTableWithID(getFormName() + SEPARADOR + getListaConsulta());
		//verifica a quantidade de linhas � maior q 1
		assertTrue(table.getRowCount() > 1 );
	}
	
	/**
	 * Testa a funcionalidade de Detalhar um registro que foi consultado.
	 * @throws SAXException 
	 * @throws IOException 
	 */
	protected void doDetalhe() throws SAXException, IOException{
		//Link para Detalhe
		WebLink linkDetalhar = getExecInfo().getResp().getLinkWithID(getFormName() + SEPARADOR + getListaConsulta() + "_0" + SEPARADOR + LINK_DETALHE);
		
		//Dispara o link de detalhe.
		linkDetalhar.click();
		
		//Obtem a referencia a pagina de detalhe
		getExecInfo().setResp( getExecInfo().getWc().getCurrentPage() );
		
		//Obtem o formulario de detalhe
		WebForm formDetalhe = getExecInfo().getResp().getFormWithName(getFormName());
		
		//Verifica se o registro foi detalhado corretamente
        String valorDescricao = TestDataManager.getInstance(this.getClass()).getStringValue(getThreadNum(), getCampoDescricao());
		assertEquals(formDetalhe.getParameterValue(getFormName() + SEPARADOR + getCampoDescricao()), valorDescricao);
	}
	
	/**
	 * Testa a funcionalidade de Remover o registro.
	 * @throws SAXException 
	 * @throws IOException 
	 */
	protected void doRemover() throws SAXException, IOException{
		//Link para remover
		WebLink linkDeletar = getExecInfo().getResp().getLinkWithID(getFormName() + SEPARADOR + LINK_DELETAR);
		
		//Dispara o link de deletar.
		linkDeletar.click();
		
		//Obtem a referencia da pagina de consulta
		getExecInfo().setResp( getExecInfo().getWc().getCurrentPage());
		
		//Verifica a mensagem de suscesso
		assertTrue(getExecInfo().getResp().getText().indexOf(getMsgRemovidoSuscesso()) > -1);
	}
	
	protected void doPrepararInserir() throws SAXException, IOException{
		//Link para a tela de inclusao
		WebLink linkInserir = getExecInfo().getResp().getLinkWithID(getFormName() + SEPARADOR + LINK_INSERIR);
		linkInserir.click();
		
		//Obtem a pagina para a insercao dos dados.
		getExecInfo().setResp( getExecInfo().getWc().getCurrentPage());
		
		//obtem o formulario
		WebForm formInclusao = getExecInfo().getResp().getFormWithName(getFormName());
		//verifica se o campo de descricao esta vazio.
		assertNull(formInclusao.getParameterValue(getCampoDescricao()));
	}
	
	/**
	 * Testa a funcionalidade de adicionar um "detalhe" detalhe do registro principal.
	 * @throws SAXException 
	 * @throws IOException 
	 */
	public void doMestreDetalheAdicionar(String beanDetalhe, String campoDescricao) throws SAXException, IOException{
		String nomeLista = LST_PREFIX + beanDetalhe;
		String nomeForm  = beanDetalhe + FORM_POSTFIX;
		
		//Abre o pop-up do registro de detalhe
		//obtem o link "Adicionar"
		WebLink linkAdicionar = getExecInfo().getResp().getLinkWithID(LINK_ADICIONAR + beanDetalhe);
		
		//invoca o linnk
		linkAdicionar.click();
		//obtem a referencia do pop-up
		WebWindow popUpWin = getExecInfo().getWc().getOpenWindows()[1];
		WebResponse popUp = popUpWin.getCurrentPage();  
		
		//obtem o formulario
		WebForm formPopUp = popUp.getFormWithName(nomeForm);
		//filtra os registros pelo dados de teste
		formPopUp.setParameter(nomeForm + SEPARADOR + campoDescricao, TEXTO_TESTE_HTTP_UNIT_PREFIX);
		//link de consultar
		WebLink linkConsultar = popUp.getLinkWithID(nomeForm + SEPARADOR + LINK_CONSULTAR);
		linkConsultar.click();
		//Obtem a pagina apos a consulta
		popUpWin = getExecInfo().getWc().getOpenWindows()[1];
		popUp = popUpWin.getCurrentPage();
		//Obtem o formulario
		formPopUp = popUp.getFormWithName(nomeForm);
		//Seleciona o checkbox do primeiro registro.
		String checkBoxName = nomeForm + SEPARADOR + LST_CONSULTA_PREFIX + beanDetalhe + "_0" + SEPARADOR + ITEM_SELECIONADO;
		//formPopUp.getParameterValue(checkBoxName);
		formPopUp.setCheckbox(checkBoxName, true);
		//dispara o link de adicionar
		linkAdicionar = popUp.getLinkWithID(nomeForm + SEPARADOR + LINK_ADICIONAR);
		linkAdicionar.click();
		
		//Obtem a pagina de detalhe
		getExecInfo().setResp( getExecInfo().getWc().getCurrentPage());
		
		//Verifica se foi adiciona na tabela de detalhe.
		WebTable tbDetalhe = getExecInfo().getResp().getTableWithID(getFormName() + SEPARADOR + SUB_VIEW_MESTRE_DETALHES_ALTERAR + SEPARADOR + nomeLista);
		//verifica a quantidade de linhas
		assertEquals(tbDetalhe.getRowCount(), 2);
	}
	
	/**
	 * Testa a funcionalidade de remover um registro "detalhe" do registro principal.
	 * @throws SAXException 
	 * @throws IOException 
	 */
	public void doMestreDetalheRemover(String beanDetalhe) throws SAXException, IOException{
		String nomeLista = LST_PREFIX + beanDetalhe;
		//AnuncioForm:mestreDetalhesSubViewAlterar:lstImagem_0:linkDeletarImagem
		//Obtem o link deletar na  lista de associacao
		WebLink linkDeletar = getExecInfo().getResp().getLinkWithID(getFormName() + SEPARADOR + SUB_VIEW_MESTRE_DETALHES_ALTERAR +SEPARADOR + nomeLista + "_0" + SEPARADOR + LINK_DELETAR + beanDetalhe);
		linkDeletar.click();//deleta o registro
		
		//verifica se foi deletado corretamente
		//Obtem a pagina de detalhe
		getExecInfo().setResp( getExecInfo().getWc().getCurrentPage());
		
		//verifica a mensagem de suscesso.
		assertTrue(getExecInfo().getResp().getText().indexOf(getMsgSalvoSuscesso()) > -1);
		
		//Verifica se foi adiciona na tabela de detalhe.
		WebTable tbDetalhe = getExecInfo().getResp().getTableWithID(getFormName() + SEPARADOR + SUB_VIEW_MESTRE_DETALHES_ALTERAR + SEPARADOR + nomeLista);
		//verifica a quantidade de linhas
		assertEquals(tbDetalhe.getRowCount(), 1);//deve ter apenas um, pois foi removida.
	}
}
